//////////////////////////////////////////////////////
// 程序名称：用中点画圆法画圆弧（选做）
// 功 能：画一些圆弧
// 编译环境：Visual Studio 2017，EasyX_20190219(beta)
// 作 者：xyqlx<mxxyqlx@qq.com>
// 最后修改：2019-3-7
#include <conio.h>
#include <graphics.h>
#include <cmath>

void CircleArc(int x0, int y0, int r, double sangle, double eangle, COLORREF color);
double PI = acos(0) * 2;

int main()
{
	// 创建绘图窗口，大小为 640x480 像素
	initgraph(640, 480);
	//填充背景为白色
	setbkcolor(WHITE);
	cleardevice();
	//开始绘制
	setlinecolor(BLUE);
	//画坐标轴
	line(320, 0, 320, 480);
	line(0, 240, 640, 240);

	double start[] = {1.2, 1.9, 3.4, 6.0,0.0,0.0};
	double end[] = {1.7, 3.4, 5.9, 3.4,1.0,6.2};
	//画角度辅助线
	setlinecolor(YELLOW);
	for (int i = 0; i < 6;++i){
		line(320, 240, 320 + 200 * cos(start[i]), 240 + 200 * sin(start[i]));
		line(320, 240, 320 + 200 * cos(end[i]), 240 + 200 * sin(end[i]));
	}
	//画圆弧
	for (int i = 0; i < 6; ++i) {
		CircleArc(320, 240, 100 + i * 10, start[i], end[i], RED);
	}

	//结束绘制
	_getch();		   // 按任意键继续
	closegraph();          // 关闭绘图窗口
	return 0;
}
//判断画点
inline void putCirclePoint(int x,int y,int seg[2],COLORREF color){
	if (seg[0] <= x && x <= seg[1]) {
		putpixel(x, y, color);
	}	
}
//x0,y0:圆弧的圆点 r:圆弧的半径 sangle,eangle:圆弧的始角度和终角度，函数会从前者向后者顺时针画一段小于整圆的弧
void CircleArc(int x0, int y0, int r, double sangle, double eangle, COLORREF color)
{
	int x, y, d;
	//记录圆弧在各象限的范围
	int point[4][2] = {{x0,x0+r},{x0-r,x0},{x0-r,x0},{x0,x0+r}};
	//使角度参数规范化为0~2PI
	if(sangle < 0)
		sangle += int(-sangle / 2 / PI + 1) *2* PI;
	if(sangle > 2*PI)
		sangle -= int(sangle / 2 / PI)*2*PI;
	if(eangle < 0)
		eangle += int(-eangle / 2 / PI + 1) * 2*PI;
	if(eangle > 2*PI)
		eangle -= int(eangle / 2 / PI)*2*PI;
	x = int(sangle * 2 / PI);
	y = int(eangle * 2 / PI);
	//计算圆弧在各象限的范围
	if(x < y || (x==y && sangle < eangle)){
		for (int i = 0; i < 4;++i){
			if(i<x || i>y){
				point[i][0] = 1;
				point[i][1] = 0;
			}
				
		}
		
	}else{
		for (int i = 0; i < 4;++i){
			if(i>y && i<x)
			{
				point[i][0] = 1;
				point[i][1] = 0;
			}
		}
	}
	point[x][x==0 || x==1] = x0 + r * cos(sangle) + 0.5;
	point[y][y==2 || y==3] = x0 + r * cos(eangle) + 0.5;
	//开始绘图
	x = 0;
	y = r;
	d = 1 - r;
	putCirclePoint(x + x0, y + y0, point[0], color);
	putCirclePoint(x + x0, -y + y0, point[3], color);
	putCirclePoint(y + x0, x + y0, point[0], color);
	putCirclePoint(y + x0, -x + y0, point[3], color);
	putCirclePoint(-x + x0, y + y0, point[1], color);
	putCirclePoint(-x + x0, -y + y0, point[2], color);
	putCirclePoint(-y + x0, x + y0, point[1], color);
	putCirclePoint(-y + x0, -x + y0, point[2], color);
	while (x < y)
	{
		if (d < 0)
		{
			d += 2 * x + 3;
			x++;
		}
		else
		{
			d += 2 * (x - y) + 5;
			x++;
			y--;
		}
		putCirclePoint(x + x0, y + y0, point[0], color);
		putCirclePoint(x + x0, -y + y0, point[3], color);
		putCirclePoint(y + x0, x + y0, point[0], color);
		putCirclePoint(y + x0, -x + y0, point[3], color);
		putCirclePoint(-x + x0, y + y0, point[1], color);
		putCirclePoint(-x + x0, -y + y0, point[2], color);
		putCirclePoint(-y + x0, x + y0, point[1], color);
		putCirclePoint(-y + x0, -x + y0, point[2], color);
	}
}